/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Movilizacion;

import GUI.GMapBean;
import commonsbeans.ApplicationBean;
import commonsbeans.SessionBean;
import entities.*;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import org.primefaces.model.DualListModel;
import persistence.*;
import persistence.exceptions.IllegalOrphanException;
import persistence.exceptions.NonexistentEntityException;
import persistence.exceptions.PreexistingEntityException;
import persistence.exceptions.RollbackFailureException;

/**
 *
 * @author Felipe Duarte
 */
@ManagedBean
@ViewScoped
public class GestionarConstrucciones implements Serializable {

    @ManagedProperty(value = "#{sessionBean}")
    private SessionBean sessionBean;
    @ManagedProperty(value = "#{applicationBean}")
    private ApplicationBean applicationBean;
    @ManagedProperty(value = "#{pickListMaterialConstruccion}")
    private PickListMaterialConstruccion pickListMaterialConstruccion;
    @ManagedProperty(value = "#{pickListBarrioConstruccion}")
    private PickListBarrioConstruccion pickListBarrioConstruccion;
    private BarrioConstruccionJpaController barrioConstruccionJpaController = null;
    private ConstruccionJpaController construccionJpaController = null;
    private BarrioJpaController barrioJpaController = null;
    private EstadoConstruccionJpaController estadoConstruccionJpaController = null;
    public List<Barrio> listaBarrios = new ArrayList<Barrio>();
    public List<EstadoConstruccion> listaEstadosConstruccion = new ArrayList<EstadoConstruccion>();
    public List<Proveedor> listaProveedores = new ArrayList<Proveedor>();
    String globeIcon = "";
    public Barrio barrio = new Barrio();
    public DualListModel<Barrio> barrios;
    public List<Barrio> barrioSource = new ArrayList<Barrio>();
    public List<Barrio> barrioTarget = new ArrayList<Barrio>();
    private List<Barrio> source, target;
    private List<Barrio> traidosBaseTarget = new ArrayList<Barrio>();
    private List<Barrio> traidosBaseSource = new ArrayList<Barrio>();
    public Construccion construccion = new Construccion();
    public List<Construccion> listaConstrucciones = new ArrayList<Construccion>();
    private boolean editar = false;
    public Construccion construccionSelected = new Construccion();
    private List<Barrio> listaBarriosConstruccion = new ArrayList<Barrio>();
    public String fechaFin = "";

    public GestionarConstrucciones() {
    }

    //Constructor
    @PostConstruct
    public void init() {
        initControllers();
        cargarBarrios();
        cargarBarriosConstruccion();
        cargarEstadosConstruccion();
        cargarResumenConstrucciones();
        globeIcon = "/resources/Globe2.png";
    }

    //<editor-fold defaultstate="collapsed" desc="Funcionalidades">
    private void cargarEstadosConstruccion() {
        listaEstadosConstruccion = estadoConstruccionJpaController.findEstadoConstruccionEntities();

    }

    public void actualizarInformacion() {
        cargarBarrios();
        cargarBarriosConstruccion();
        cargarResumenConstrucciones();
    }

    private void cargarResumenConstrucciones() {
        listaConstrucciones = construccionJpaController.findConstruccionCiudad(sessionBean.getUsuarioActual().getCiudadIdCiudad().getIdCiudad());

    }

    public void handleDateSelect() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        SimpleDateFormat format = new SimpleDateFormat("d/M/yyyy");
        if (construccion.getFechaInicialConstruccion() != null) {
            fechaFin = format.format(construccion.getFechaInicialConstruccion());
        }
    }

    private void cargarBarrios() {
        listaBarrios = new ArrayList<Barrio>();
        listaBarrios = barrioJpaController.getBarrio_Habilitados_Ciudad(sessionBean.getUsuarioActual().getCiudadIdCiudad());
    }

//    private void cargarProveedores() {
//        listaProveedores = proveedorJpaController.getProveedorPorCiudadAbastecimiento(sessionBean.getUsuarioActual().getCiudadIdCiudad());
//    }
    public void cargarBarriosConstruccion() {
        source = new ArrayList<Barrio>();
        source = listaBarrios;
        target = new ArrayList<Barrio>();
        pickListBarrioConstruccion.setBarrio(new DualListModel<Barrio>());
        pickListBarrioConstruccion.getBarrio().setSource(source);
        pickListBarrioConstruccion.getBarrio().setTarget(target);
    }

    private void editarConstruccion() {
        try {
            construccionJpaController.edit(construccion);
            editarBarrios();
        } catch (IllegalOrphanException ex) {
            Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NonexistentEntityException ex) {
            Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RollbackFailureException ex) {
            Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Metodo para editar las construcciones
     */
    private void editarBarrios() throws PreexistingEntityException, RollbackFailureException, Exception {


        List<Barrio> listaAlterna = new ArrayList<Barrio>();
        boolean corregido = false;
        int idBarrioConstruccion = barrioConstruccionJpaController.getIdMax();
        for (int i = 0; i < construccion.getBarrioConstruccionList().size(); i++) {
            listaAlterna.add(construccion.getBarrioConstruccionList().get(i).getIdBarrioBarrioConstruccion());
        }
        for (int i = 0; i < listaAlterna.size(); i++) {
            if (pickListBarrioConstruccion.getBarrio().getSource().contains(listaAlterna.get(i))) {
                try {
                    barrioConstruccionJpaController.destroy(construccion.getBarrioConstruccionList().get(i).getIdBarrioConstruccion());
                } catch (NonexistentEntityException ex) {
                    Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
                } catch (RollbackFailureException ex) {
                    Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
                } catch (Exception ex) {
                    Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
                }
            }



        }
        for (int j = 0; j < pickListBarrioConstruccion.getBarrio().getTarget().size(); j++) {
            if (!listaAlterna.contains(pickListBarrioConstruccion.getBarrio().getTarget().get(j))) {
                idBarrioConstruccion++;
                BarrioConstruccion bc = new BarrioConstruccion();
                bc.setIdBarrioBarrioConstruccion(pickListBarrioConstruccion.getBarrio().getTarget().get(j));
                bc.setIdBarrioConstruccion(idBarrioConstruccion);
                bc.setIdConstruccionBarrioConstruccion(construccion);
                barrioConstruccionJpaController.create(bc);
            }
        }
        if (construccion.getBarrioConstruccionList().isEmpty()) {
            guardarBarriosConstruccion(construccion);
        }

    }

    /**
     * Metodo para guardar las construcciones, verificando si lo que se esta
     * guardando es seleccionado desde la tabla o es una construcción nueva
     */
    public void guardarConstruccion() {

        if (!editar) {
            if (construccion.getLongitudConstruccion() == null) {
                throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Debe ubicar el punto de acopio en el mapa"));
            } else {
                try {
                    construccion.setIdConstruccion(construccionJpaController.getIdMax() + 1);
                    construccion.setEstadoConstruccionIdEstadoConstruccion(estadoConstruccionJpaController.findEstadoConstruccion(1));
                    construccion.setCiudadConstruccion(sessionBean.getUsuarioActual().getCiudadIdCiudad().getIdCiudad());
                    construccionJpaController.create(construccion);
                    guardarBarriosConstruccion(construccion);
                    showSuccessMessage("se ha registrado la construcción de manera éxitosa");
                    listaConstrucciones.add(construccion);
                    limpiarFormulario();
                } catch (PreexistingEntityException ex) {
                    Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
                } catch (RollbackFailureException ex) {
                    Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
                } catch (Exception ex) {
                    Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } else {
            editarConstruccion();
            editar = false;
            showSuccessMessage("se ha modificado la construcción de manera éxitosa");
            limpiarFormulario();
            listaBarrios.clear();
            cargarBarrios();
            cargarBarriosConstruccion();
        }
        init();

    }

    /**
     * Metodo para guardar los id's de los barrios con el id de la construccion
     * en la tabla que rompe la relación muchos a muchos
     */
    private void guardarBarriosConstruccion(Construccion construccion) {

        int idBarrioConstruccion = barrioConstruccionJpaController.getIdMax();
        for (int i = 0; i < pickListBarrioConstruccion.getBarrio().getTarget().size(); i++) {
            try {
                idBarrioConstruccion++;
                BarrioConstruccion bc = new BarrioConstruccion();
                bc.setIdBarrioBarrioConstruccion(pickListBarrioConstruccion.getBarrio().getTarget().get(i));
                bc.setIdBarrioConstruccion(idBarrioConstruccion);
                bc.setIdConstruccionBarrioConstruccion(construccion);
                barrioConstruccionJpaController.create(bc);
            } catch (PreexistingEntityException ex) {
                Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
            } catch (RollbackFailureException ex) {
                Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(GestionarConstrucciones.class.getName()).log(Level.SEVERE, null, ex);
            }
        }


    }

    /**
     * Metodo para selccionar el barrio de la tabla
     */
    public void rowSelected() {

        List<Barrio> listaNueva = new ArrayList<Barrio>();
        pickListBarrioConstruccion.getBarrio().setSource(listaNueva);
        pickListBarrioConstruccion.getBarrio().setTarget(listaNueva);
        target = new ArrayList<Barrio>();
        construccion = construccionSelected;
        editar = true;
        List<Barrio> listaAlterna = new ArrayList<Barrio>();
        for (int i = 0; i < construccion.getBarrioConstruccionList().size(); i++) {
            listaAlterna.add(construccion.getBarrioConstruccionList().get(i).getIdBarrioBarrioConstruccion());

        }
        listaBarriosConstruccion = listaAlterna;
        for (int i = 0; i < listaAlterna.size(); i++) {
            target.add(listaAlterna.get(i));
            traidosBaseTarget.add(listaAlterna.get(i));
            source.remove(target.get(i));
        }
        for (int i = 0; i < source.size(); i++) {
            traidosBaseSource.add(source.get(i));
        }
        source = listaBarrios;
        source.removeAll(target);
        pickListBarrioConstruccion.getBarrio().setSource(source);
        pickListBarrioConstruccion.getBarrio().setTarget(target);
        cargarBarrios();
    }

    /**
     * Metodo para deselccionar el barrio de la tabla
     */
    public void onRow() {
        construccion = new Construccion();
        construccionSelected = new Construccion();
        cargarBarrios();
        cargarBarriosConstruccion();
        editar = false;
    }

    private void limpiarFormulario() {
        construccion = new Construccion();
        construccionSelected = new Construccion();
        cargarBarriosConstruccion();
        Float latitud = 0.F;

    }

    public void showSuccessMessage(String detail) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Operación exitosa", detail);
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

    /**
     * Muestra mensajes para notificar error en la transacción
     *
     * @param detail Detalle del error
     */
    public void showErrorMessage(String detail) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", detail);
        FacesContext.getCurrentInstance().addMessage(null, message);
    }
//</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Getter's y setter's">
    public SessionBean getSessionBean() {
        return sessionBean;
    }

    public void setSessionBean(SessionBean sessionBean) {
        this.sessionBean = sessionBean;
    }

    public String getFechaFin() {
        return fechaFin;
    }

    public void setFechaFin(String fechaFin) {
        this.fechaFin = fechaFin;
    }

    public ApplicationBean getApplicationBean() {
        return applicationBean;
    }

    public List<EstadoConstruccion> getListaEstadosConstruccion() {
        return listaEstadosConstruccion;
    }

    public void setListaEstadosConstruccion(List<EstadoConstruccion> listaEstadosConstruccion) {
        this.listaEstadosConstruccion = listaEstadosConstruccion;
    }

    public void setApplicationBean(ApplicationBean applicationBean) {
        this.applicationBean = applicationBean;
    }

    public String getGlobeIcon() {
        return globeIcon;
    }

    public void setGlobeIcon(String globeIcon) {
        this.globeIcon = globeIcon;
    }

    public PickListMaterialConstruccion getPickListMaterialConstruccion() {
        return pickListMaterialConstruccion;
    }

    public void setPickListMaterialConstruccion(PickListMaterialConstruccion pickListMaterialConstruccion) {
        this.pickListMaterialConstruccion = pickListMaterialConstruccion;
    }

    public List<Barrio> getListaBarrios() {
        return listaBarrios;
    }

    public void setListaBarrios(List<Barrio> listaBarrios) {
        this.listaBarrios = listaBarrios;
    }

    public List<Proveedor> getListaProveedores() {
        return listaProveedores;
    }

    public void setListaProveedores(List<Proveedor> listaProveedores) {
        this.listaProveedores = listaProveedores;
    }

    public Barrio getBarrio() {
        return barrio;
    }

    public void setBarrio(Barrio barrio) {
        this.barrio = barrio;
    }

    public DualListModel<Barrio> getBarrios() {
        return barrios;
    }

    public void setBarrios(DualListModel<Barrio> barrios) {
        this.barrios = barrios;
    }

    public List<Barrio> getBarrioSource() {
        return barrioSource;
    }

    public void setBarrioSource(List<Barrio> barrioSource) {
        this.barrioSource = barrioSource;
    }

    public List<Barrio> getBarrioTarget() {
        return barrioTarget;
    }

    public void setBarrioTarget(List<Barrio> barrioTarget) {
        this.barrioTarget = barrioTarget;
    }

    public List<Barrio> getSource() {
        return source;
    }

    public void setSource(List<Barrio> source) {
        this.source = source;
    }

    public List<Barrio> getTarget() {
        return target;
    }

    public Construccion getConstruccionSelected() {
        return construccionSelected;
    }

    public void setConstruccionSelected(Construccion construccionSelected) {
        this.construccionSelected = construccionSelected;
    }

    public void setTarget(List<Barrio> target) {
        this.target = target;
    }

    public List<Barrio> getTraidosBaseTarget() {
        return traidosBaseTarget;
    }

    public void setTraidosBaseTarget(List<Barrio> traidosBaseTarget) {
        this.traidosBaseTarget = traidosBaseTarget;
    }

    public List<Barrio> getTraidosBaseSource() {
        return traidosBaseSource;
    }

    public void setTraidosBaseSource(List<Barrio> traidosBaseSource) {
        this.traidosBaseSource = traidosBaseSource;
    }

    public Construccion getConstruccion() {
        return construccion;
    }

    public void setConstruccion(Construccion construccion) {
        this.construccion = construccion;
    }

    public PickListBarrioConstruccion getPickListBarrioConstruccion() {
        return pickListBarrioConstruccion;
    }

    public void setPickListBarrioConstruccion(PickListBarrioConstruccion pickListBarrioConstruccion) {
        this.pickListBarrioConstruccion = pickListBarrioConstruccion;
    }

    public List<Construccion> getListaConstrucciones() {
        return listaConstrucciones;
    }

    public void setListaConstrucciones(List<Construccion> listaConstrucciones) {
        this.listaConstrucciones = listaConstrucciones;
    }

//</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Inicializar los controladores">
    public void initControllers() {
        FacesContext context = FacesContext.getCurrentInstance();
        construccionJpaController = (ConstruccionJpaController) context.getELContext().getELResolver().getValue(context.getELContext(), null, "construccionJpaController");
        estadoConstruccionJpaController = (EstadoConstruccionJpaController) context.getELContext().getELResolver().getValue(context.getELContext(), null, "estadoConstruccionJpaController");
        barrioConstruccionJpaController = (BarrioConstruccionJpaController) context.getELContext().getELResolver().getValue(context.getELContext(), null, "barrioConstruccionJpaController");
        barrioJpaController = (BarrioJpaController) context.getELContext().getELResolver().getValue(context.getELContext(), null, "barrioJpaController");
    }
//</editor-fold>
}
